package com.pai4j.message.interceptor;

import com.pai4j.common.util.RedisUtil;
import com.pai4j.message.core.interceptor.MessageInterceptor;
import com.pai4j.message.model.MessageContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

/**
 * 去重拦截器
 * 防止短时间内重复发送相同的消息
 * 
 * 使用Redis存储消息指纹，默认有效期60秒
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
@Component
@ConditionalOnProperty(prefix = "pai4j.message.interceptors.duplicate", name = "enabled", havingValue = "true", matchIfMissing = true)
public class DuplicateMessageInterceptor implements MessageInterceptor {

    @Autowired(required = false)
    private RedisUtil redisUtil;

    /**
     * 去重时间窗口（秒）
     */
    private static final long DUPLICATE_WINDOW = 60L;

    /**
     * 缓存Key前缀
     */
    private static final String CACHE_KEY_PREFIX = "message:duplicate:";

    @Override
    public String getName() {
        return "duplicate-check";
    }

    @Override
    public boolean intercept(MessageContext context) {
        if (redisUtil == null) {
            log.debug("RedisUtil未注入，跳过去重检查");
            return true;
        }

        try {
            // 生成消息指纹
            String fingerprint = generateFingerprint(context);
            String cacheKey = CACHE_KEY_PREFIX + fingerprint;

            // 检查是否重复
            if (redisUtil.exists(cacheKey)) {
                log.warn("检测到重复消息，拦截发送: fingerprint={}, sender={}, receiver={}", 
                        fingerprint, context.getSenderId(), context.getReceiverId());
                return false;
            }

            // 记录消息指纹
            redisUtil.set(cacheKey, "1", DUPLICATE_WINDOW);
            
            log.debug("消息去重检查通过: fingerprint={}", fingerprint);
            return true;

        } catch (Exception e) {
            log.error("去重检查异常，允许通过: error={}", e.getMessage(), e);
            return true; // 异常时允许通过，不影响业务
        }
    }

    @Override
    public int getOrder() {
        return 10; // 高优先级，第一个执行
    }

    /**
     * 生成消息指纹
     * 基于：发送者+接收者+消息类型+资源ID
     */
    private String generateFingerprint(MessageContext context) {
        return String.format("%s:%s:%s:%s:%s",
                context.getSenderId(),
                context.getReceiverId(),
                context.getType(),
                context.getResourceType() != null ? context.getResourceType() : "",
                context.getResourceId() != null ? context.getResourceId() : ""
        ).hashCode() + "";
    }

    @Override
    public String getDescription() {
        return "去重拦截器 - 防止" + DUPLICATE_WINDOW + "秒内重复发送相同消息";
    }
}

